﻿using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Swashbuckle.AspNetCore.SwaggerUI;
using ZT.Core.IService;
using ZT.Core.MiddleWare;
using ZT.Core.ORM;
using ZT.Core.Service;
using ZT.WxHelper;

namespace ZT.Core.API
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            WxConfig.LoadConfig();
            Service.EventBus.EventBus.InstanceForXml(configuration);
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //数据库连接字符串
            var constr = Configuration["ConnectionStrings:pgconn"];
            services.AddDbContext<PGdb>(opt =>
            {
                opt.UseNpgsql(constr);
            });
            //跨域
            services.AddCors(opt =>
            {
                opt.AddPolicy("any", build =>
                 {
                     build.AllowAnyHeader()
                          .AllowAnyMethod()
                          .SetIsOriginAllowed(_=>true)
                          .AllowCredentials();
                 });
            });
            /*****************服务注入*****************/
            services.AddScoped<IUnitOfWork, UnitOfWork>();
            services.AddScoped<IAuthUser, AuthUserService>();
            services.AddScoped<ISysLog, SysLogService>();
            services.AddScoped<IAttachFile, AttachFileService>();
            services.AddScoped<IFlow, FlowService>();
            services.AddScoped<IWechat, WechatService>();
            /******************************************/

            //swagger文档
            services.AddSwaggerGen(opt =>
            {
                opt.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
                {
                    Version = "v1",
                    Title = "API 文档",
                    Description = "by HanLan"
                });

                opt.OperationFilter<AddHeaderParatmeter>();
                opt.DocumentFilter<SwaggerDocTag>();
                opt.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory + "", "ZT.Core.API.xml"));
                opt.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory + "", "ZT.Core.Model.xml"));
                opt.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory + "", "ZT.Core.Dto.xml"));
                opt.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory + "", "ZT.Core.Utility.xml"));
                opt.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory + "", "ZT.Core.Enums.xml"));

            });

            services.AddMvc(opt =>
            {
                /*****过滤器******/
                opt.Filters.Add(typeof(MiddleWare.ZTActionFilter));
                opt.Filters.Add(typeof(MiddleWare.ExceptionFilter));

            }).SetCompatibilityVersion(CompatibilityVersion.Version_3_0).AddNewtonsoftJson(opt => { opt.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver(); /*取消默认驼峰序列化*/});
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //启用跨域规则
            app.UseCors("any");
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //启用swagger
            app.UseSwagger(c => { c.RouteTemplate = "swagger/{documentName}/swagger.json"; });
            app.UseSwaggerUI(c =>
            {
                c.RoutePrefix = string.Empty;
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1 docs");
                c.DocExpansion(DocExpansion.None);
            });

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot")),
                RequestPath = "/wwwroot"
            });
            
        }
    }
}
